package com.danicsoft.daide.command;

import com.danicsoft.daide.token.StandardToken;
import com.danicsoft.daide.token.Token;
import com.danicsoft.daide.token.TokenGroup;
import com.danicsoft.daide.token.TokenMap;

/**
 * Represents a unit's position on the board. It contains the unit's provincial
 * location, the power it is owned by and the type of unit.
 * 
 * @author Daniel Yule (daniel.yule@gmail.com)
 * @version 1.0
 */
public class UnitPos implements IOTarget {
	/**
	 * The power this unit is owned by.
	 */
	public StandardToken power;

	/**
	 * The province this unit is located in. This could be either a single token
	 * or a group with the province and the coast token in it.
	 */
	public Token province;

	/**
	 * The type of this unit.
	 */
	public StandardToken unit_type;

	/**
	 * If this unit must choose one of the retreat options present.
	 */
	protected boolean isRetreating = false;

	public void doIO(TokenIO tokenIO, TokenGroup tokens) throws ParseException {
		TokenGroup thisGroup = tokenIO.subGroup(tokens);
		handleSubGroup(tokenIO, thisGroup);
	}

	/**
	 * Loads or saves the actual data contained in this unit position.
	 * 
	 * @param tokenIO
	 *        The IO to use to read or write the tokens.
	 * @param tokens
	 *        The tokens to read or write.
	 * @throws ParseException
	 *         If there was a problem reading the tokens.
	 */
	protected void handleSubGroup(TokenIO tokenIO, TokenGroup tokens) throws ParseException {
		power = (StandardToken) tokenIO.doToken(tokens, power, TokenMap.powers);
		unit_type = (StandardToken) tokenIO.doToken(tokens, unit_type, TokenMap.unit_types);
		province = tokenIO.doToken(tokens, province, TokenMap.provinces);
	}

	public IOTarget newInstance() {
		return new UnitPos();
	}

	@Override
	public String toString() {
		return '(' + power.toString() + ' ' + province + ' ' + unit_type + ')';
	}

	@Override
	public boolean equals(Object obj) {
		return obj == null ? false : obj.hashCode() == hashCode();
	}

	@Override
	public int hashCode() {
		return power.hashCode() + province.hashCode() + unit_type.hashCode();
	}
	


	/**
	 * Gets whether or not this is a position that includes retreat information.
	 * 
	 * @return True if the position given must retreat.
	 */
	public boolean isRetreating() {
		return isRetreating;
	}

}
